<?php

class Core_Component_Account_Model_Account extends Soul_Model_Entity_Base {
	
	protected $tableName = '{t}account_account';
	
	public function getUser(){
		if(!$this->issetData('user')){
			$this->data['user'] = App::loadModel('account/information', $this->getId());
		}
		return $this->data['user'];
	}
	
	public function getChildAccounts(){
		if(!$this->issetData('child_accounts')){
			$this->data['child_accounts'] = $this->getQuery()
				->where('`id_path` like :idPath:s')
				->addParameter('idPath', $this->getIdPath().'%')		
				->fetchCollection();
		}
		return $this->data['child_accounts'];
	}
	
	public function getGroup(){
		if(!$this->issetData('group')){
			$this->data['group'] = App::getModel('account/group')->load($this->getGroupId());
		}
		return $this->data['group'];		
	}

    public function getRoles() {
    	if(!$this->hasData('roles')){
    		$this->data['roles'] = App::getModel('account/role')->getQuery()
    									->where('`code` in (:code:a)')
    									->addParameter('code', $this->getRoleCodes())
    									->fetchCollection();
    	}
    	return $this->getData('roles');
    }
    
    public function getActions() {
    	if(!$this->hasData('actions')){
    		$this->data['actions'] = App::getModel('account/action')->getQuery()
    									->condition('code', $this->getActionCodes(), 'in')
    									->fetchCollection();
    	}
    	return $this->getData('actions');
    }    

    public function validate() {
        if ($this->isNew()) {
        	if($this->checkExists(array('user_name'=>$this->getUserName()))){
        		throw new Core_Component_Account_Exception(Core_Component_Account_Exception::ACCOUNT_REPEATED);
        	}
        }
        return parent::validate();
    }
    
    public function randomPassword(){
    	$result = Soul_Util_Random::randomCharacters(8);
    	$sql = 'UPDATE `'.$this->getTableName().'`'
    		 . ' SET `password`=:password:s,`operator`=:operator:s,`operation_time`=:operationTime:d'
    		 . ' WHERE `id`=:id:i';
    	$this->getDb()->setSql($sql, array('password'=>md5($result),
    									   'operator'=>$GLOBALS[RC]->getIdentity()->getName(),
    									   'operationTime'=>date('Y-m-d H:i:s'),
    									   'id'=>$this->getIdValue()))->execute();
    	return $result;
    }    
    
    public function changePassword($oldPassword, $newPassword){
    	if(md5($oldPassword) != $this->getPassword()){
    		throw new Core_Component_Account_Exception(Core_Component_Account_Exception::PASSWORD_ERROR);
    	}
    	$sql = 'UPDATE `'.$this->getTableName().'`'
    		 . ' SET `password`=:password:s,`operator`=:operator:s,`operation_time`=:operationTime:d'
    		 . ' WHERE `id`=:id:i';
    	$this->getDb()->setSql($sql, array('password'=>md5($newPassword), 
    									   'operator'=>$GLOBALS[RC]->getIdentity()->getName(),
    									   'operationTime'=>date('Y-m-d H:i:s'),
    									   'id'=>$this->getIdValue()))->execute();
    	return $this;
    }
    
    protected function afterInsert() {
    	$this->markNoChanged();
    	$idPath = $this->getId().'_';
    	if($this->issetData('parent_id') && $this->getParentId() != 0){
    		$parent = new self();
    		$idPath = $parent->load($this->getParentId())->getIdPath().$idPath;
    	}
    	$sql = 'UPDATE `'.$this->getTableName().'` SET'
    		 . ' `id_path`=:idPath:s'
    		 . ' WHERE `id` =:id:i';
    	$this->getDb()->setSql($sql, array('id'=>$this->getId(), 'idPath'=>$idPath))->execute();
    }
    
    protected function afterUpdate(){
    	if($this->propertyIsChanged('parent_id')){
    		$parent = new self();
    		if($this->issetData('parent_id') && $this->getParentId() != 0){
    			$parent->load($this->issetData('parent_id'));
    			$idPath = $parent->load($this->getParentId())->getIdPath().$this->getId().'_';
    		}else{
    			$idPath = $this->getId().'_';
    		}
	    	$sql = 'UPDATE `'.$this->getTableName().'` SET'
	    		 . ' `id_path`=concat(:newIdPath:s, substring(`id_path`,'.(strlen($oldIdPath) + 1).'))'
	    		 . ' WHERE `id_path` LIKE :oldIdPath:s';
	    	$this->getDb()->setSql($sql, array('newIdPath'=>$idPath, 'oldIdPath'=>$this->getIdPath().'%'))->execute();
    	}
    }

    protected function initializeProperties() {
        $this->createProperty('id', 'integer', TRUE, TRUE);
        $this->createProperty('user_name', 'string')
                ->setLabel('account.username')
                ->addRule(new Soul_Validation_Rule_MinLength(6))
                ->addRule(new Soul_Validation_Rule_Character())
                ->setLength(16)
                ->setRequired(TRUE)
                ->setUpdateable(FALSE);
        $this->createProperty('password', 'string')
                ->setLabel('account.password')
                ->addRule(new Soul_Validation_Rule_MinLength(6))
                ->setLength(16)
                ->setRequired(TRUE)
                ->setUpdateable(FALSE);
        $this->createProperty('email', 'email')
                ->setLabel('system.label.email')
                ->setRequired(TRUE);
        $this->createProperty('role_codes', 'array')
                ->setLabel('account.roles')
                ->setRequired(TRUE)
                ->setInputType('select');
        $this->createProperty('action_codes', 'array')
                ->setLabel('account.actions')
                ->setInputType('select');
        $this->createProperty('parent_id', 'integer')
                ->setLabel('account.owner_user')
                ->setInputType('select')
                ->setDefaultValue(0);        
        $this->createProperty('expiry_time', 'datetime')
                ->setLabel('account.expiry_time')
                ->setDefaultValue(NULL);
        $this->createProperty('status', 'string')
                ->setInputType(NULL);    
        $this->createProperty('id_path', 'string')
                ->setInputType(NULL);
    }

}